package com.joker.airoleplayplatformback.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;

/**
 * 文本转语音工具类
 * @author feixiang.li
 * @since 2025-09-28
 */
@Slf4j
public class TextToSpeechUtils {

    private static final String API_URL = "https://openai.qiniu.com/v1/voice/tts";
    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * TTS响应结果类
     */
    @Data
    public static class TTSResponse {
        private String reqid;
        private String operation;
        private int sequence;
        private byte[] audioData;
        private int duration;

        public TTSResponse(String reqid, String operation, int sequence,
                           byte[] audioData, int duration) {
            this.reqid = reqid;
            this.operation = operation;
            this.sequence = sequence;
            this.audioData = audioData;
            this.duration = duration;
        }


        /**
         * 保存为MP3文件
         */
        public void saveToFile(String filePath) {
            try {
                Path path = Paths.get(filePath);
                Files.write(path, audioData);
                System.out.println("MP3文件已保存: " + path.toAbsolutePath());
            } catch (Exception e) {
                throw new RuntimeException("保存MP3文件失败", e);
            }
        }

        /**
         * 获取音频数据大小
         */
        public int getAudioSize() {
            return audioData != null ? audioData.length : 0;
        }

        @Override
        public String toString() {
            return String.format("TTS响应: reqid=%s, 时长=%dms, 音频大小=%d bytes",
                    reqid, duration, getAudioSize());
        }
    }

    public static String removeSpacesKeepPunctuation(String text) {
        if (text == null) {
            return null;
        }

        // 正则表达式说明：
        // \\s - 匹配所有空白字符（空格、换行、制表符等）
        // 保留字母、数字、中文和常见标点符号
        return text.replaceAll("\\s+", "");
    }

    /**
     * 文本转语音 - 返回完整的TTS响应对象
     */
    public static TTSResponse textToSpeech(String text, String voiceType, String encoding, double speedRatio, String apiKey) {
        try {
            log.info("开始进行文本转语音");
            // 去除特殊字符串
            text = removeSpacesKeepPunctuation(text);
            // 构建请求JSON
            String requestBody = String.format(
                    "{\"audio\": {\"voice_type\": \"%s\", \"encoding\": \"%s\", \"speed_ratio\": %.1f}, " +
                            "\"request\": {\"text\": \"%s\"}}",
                    voiceType, encoding, speedRatio, text
            );

            log.info("文本转语音-> 请求体: " + requestBody);

            // 创建HTTP请求
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(API_URL))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey)
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                    .build();

            // 发送请求
            HttpClient client = HttpClient.newHttpClient();
            HttpResponse<String> response = client.send(
                    request, HttpResponse.BodyHandlers.ofString());

            // 解析响应
            if (response.statusCode() == 200) {
                return parseTTSResponse(response.body());
            } else {
                throw new RuntimeException("TTS请求失败: HTTP " +
                        response.statusCode() + " - " + response.body());
            }

        } catch (Exception e) {
            throw new RuntimeException("文本转语音失败", e);
        }
    }

    /**
     * qiniu_zh_female_xyqxxj
     * 简化版本 - 使用默认参数
     */
    public static TTSResponse textToSpeech(String text, String voiceType, String encoding, String apiKey) {
        return textToSpeech(
                text,
                voiceType,
                encoding,
                1.0,
                apiKey
        );
    }

    /**
     * 解析TTS响应
     */
    private static TTSResponse parseTTSResponse(String responseBody) {
        try {
            JsonNode root = mapper.readTree(responseBody);

            // 解析基本字段
            String reqid = root.get("reqid").asText();
            String operation = root.get("operation").asText();
            int sequence = root.get("sequence").asInt();

            // 解析duration
            int duration = 0;
            JsonNode additionNode = root.get("addition");
            if (additionNode != null && additionNode.has("duration")) {
                duration = additionNode.get("duration").asInt();
            }

            // 解析data字段（base64编码的音频数据）
            String base64Data = root.get("data").asText();
            byte[] audioData = Base64.getDecoder().decode(base64Data);

            return new TTSResponse(reqid, operation, sequence, audioData, duration);

        } catch (Exception e) {
            throw new RuntimeException("解析TTS响应失败: " + e.getMessage(), e);
        }
    }

    /**
     * 文本转语音并直接保存为MP3文件
     */
    public static void textToSpeechFile(String text, String voiceType, String encoding, double speedRatio, String filePath, String apiKey) {
        TTSResponse response = textToSpeech(text, voiceType, encoding, speedRatio, apiKey);
        response.saveToFile(filePath);
    }

    /**
     * 只获取音频数据的简化方法
     */
    public static byte[] textToSpeechAudio(String text, String voiceType, String encoding, String apiKey) {
        TTSResponse response = textToSpeech(text, voiceType, encoding, apiKey);
        return response.getAudioData();
    }

    public static void main(String[] args) {
        String voiceType = "qiniu_zh_male_cxkjns";
        String path = "/Users/luckincoffee/Desktop/code/2025-09-07-canel/ai-roleplay-platform/1.mp3";
        String encoding = "mp3";
        String apiKey = "sk-05bc0a43150ec29cfe555de2ffcb22a116ff5ee5e7a234c788077d54558e3c85";
        textToSpeechFile("今天是2023年5月10日，星期五。", voiceType,
                encoding, 1.0, path, apiKey);
    }
}